package com.msb.mall.product.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.msb.common.vo.CommonPageReq;
import com.msb.common.vo.CommonResult;
import com.msb.mall.core.dao.product.SkuInfoDao;
import com.msb.mall.core.entity.product.SkuImagesEntity;
import com.msb.mall.core.entity.product.SkuInfoEntity;
import com.msb.mall.core.entity.product.SpuInfoDescEntity;
import com.msb.mall.core.vo.product.SeckillVO;
import com.msb.mall.core.vo.product.SkuItemSaleAttrVo;
import com.msb.mall.core.vo.product.SpuItemGroupAttrVo;
import com.msb.mall.core.vo.product.SpuItemVO;
import com.msb.mall.product.feign.SeckillFeignService;
import com.msb.mall.product.service.*;
import org.apache.commons.lang.StringUtils;
//import org.apache.skywalking.apm.toolkit.trace.Tag;
//import org.apache.skywalking.apm.toolkit.trace.Tags;
//import org.apache.skywalking.apm.toolkit.trace.Trace;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.msb.common.utils.PageUtils;
import com.msb.common.utils.Query;


@Service("skuInfoService")
public class SkuInfoServiceImpl extends ServiceImpl<SkuInfoDao, SkuInfoEntity> implements SkuInfoService {

    @Autowired
    ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    SkuImagesService skuImagesService;

    @Autowired
    SpuInfoDescService spuInfoDescService;

    @Autowired
    AttrGroupService attrGroupService;

    @Autowired
    SkuSaleAttrValueService skuSaleAttrValueService;

    @Autowired
    SeckillFeignService seckillFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<SkuInfoEntity> page = this.page(
                new Query<SkuInfoEntity>().getPage(params),
                new QueryWrapper<SkuInfoEntity>()
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageCondition(CommonPageReq<Map<String, Object>> req) {
        Page<SkuInfoEntity> page = new Page<>(req.getCurrPage(), req.getPageSize());

        Map<String, Object> param = req.getData();
        LambdaQueryWrapper<SkuInfoEntity> queryWrapper = new LambdaQueryWrapper<>();
        if (param != null) {
            Integer zero = Integer.valueOf(0);
            Integer categoryId = (Integer) param.get("categoryId");
            if(categoryId != null && !zero.equals(categoryId)) {
                queryWrapper.eq(SkuInfoEntity::getCatalogId, categoryId);
            }
            Integer brandId = (Integer) param.get("brandId");
            if(brandId != null && !zero.equals(brandId)) {
                queryWrapper.eq(SkuInfoEntity::getBrandId, brandId);
            }
            queryWrapper.like(StringUtils.isNotEmpty((String) param.get("name")),
                    SkuInfoEntity::getSkuName, param.get("name"));
            queryWrapper.gt(param.get("min")!=null, SkuInfoEntity::getPrice, param.get("min"));
            queryWrapper.lt(param.get("max")!=null, SkuInfoEntity::getPrice, param.get("max"));
        }

        IPage<SkuInfoEntity> skuInfoEntityIPage = baseMapper.selectPage(page, queryWrapper);
        return new PageUtils(skuInfoEntityIPage);
    }

    /**
     * 根据spu查询所有的sku信息
     * @param spuId
     * @return
     */
    @Override
    public List<SkuInfoEntity> getSkusBySpuId(Long spuId) {
        LambdaQueryWrapper<SkuInfoEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SkuInfoEntity::getSpuId, spuId);
        return this.baseMapper.selectList(queryWrapper);
    }

//    @Trace
//    @Tags({
//            @Tag(key="item",value = "returnedObj")
//            ,@Tag(key="itemParam",value = "arg[0]")
//    })
    @Override
    public SpuItemVO item(Long skuId) throws ExecutionException, InterruptedException {
        SpuItemVO vo = new SpuItemVO();
        CompletableFuture<SkuInfoEntity> skuInfoFuture = CompletableFuture.supplyAsync(() -> {
            // 1.sku的基本信息 pms_sku_info
            SkuInfoEntity skuInfoEntity = getById(skuId);
            vo.setInfo(skuInfoEntity);

            return skuInfoEntity;
        }, threadPoolExecutor);

        CompletableFuture<Void> saleFuture = skuInfoFuture.thenAcceptAsync((res) -> {
            // 3.获取spu中的销售属性的组合
            List<SkuItemSaleAttrVo> saleAttrs = skuSaleAttrValueService
                    .getSkuSaleAttrValueBySpuId(res.getSpuId());
            vo.setSaleAttrs(saleAttrs);
        }, threadPoolExecutor);

        CompletableFuture<Void> spuFuture = skuInfoFuture.thenAcceptAsync((res) -> {
            // 4.获取SPU的介绍
            SpuInfoDescEntity spuInfoDescEntity = spuInfoDescService.getById(res.getSpuId());
            vo.setDesc(spuInfoDescEntity);
        }, threadPoolExecutor);


        CompletableFuture<Void> groupFuture = skuInfoFuture.thenAcceptAsync((res) -> {
            // 5.获取SPU的规格参数
            List<SpuItemGroupAttrVo> groupAttrVo = attrGroupService
                    .getAttrgroupWithSpuId(res.getSpuId(), res.getCatalogId());
            vo.setBaseAttrs(groupAttrVo);
        }, threadPoolExecutor);

        CompletableFuture<Void> imageFuture = CompletableFuture.runAsync(() -> {
            // 2.sku的图片信息pms_sku_images
            List<SkuImagesEntity> images = skuImagesService.getImagesBySkuId(skuId);
            vo.setImages(images);
        }, threadPoolExecutor);

        CompletableFuture<Void> seckillFuture = CompletableFuture.runAsync(() -> {
            // 查询商品的秒杀活动
            CommonResult r = seckillFeignService.getSeckillSessionBySkuId(skuId);
            if(r.getCode() == 200){
                SeckillVO seckillVO = JSON.parseObject(r.getData().toString(),SeckillVO.class);
                vo.setSeckillVO(seckillVO);
            }
        }, threadPoolExecutor);


        CompletableFuture.allOf(saleFuture,spuFuture,imageFuture,groupFuture,seckillFuture).get();
        return vo;
    }

    @Override
    public List<String> getSkuSaleAttrs(Long skuId) {
        return baseMapper.getSkuSaleAttrs(skuId);
    }

}
